import {hasClosestBlock, isInEmbedBlock} from "../protyle/util/hasClosest";
import {focusByRange, getEditorRange} from "../protyle/util/selection";

export const bgFade = (element: Element) => {
    element.classList.add("protyle-wysiwyg--hl");
    setTimeout(function () {
        element.classList.remove("protyle-wysiwyg--hl");
    }, 1024);
};

export const highlightById = (protyle: IProtyle, id: string, position: ScrollLogicalPosition = "nearest") => {
    let nodeElement: HTMLElement;
    const protyleElement = protyle.wysiwyg.element;
    if (!protyle.preview.element.classList.contains("fn__none")) {
        // 预览定位
        nodeElement = document.getElementById(id);
        if (nodeElement) {
            protyle.preview.element.scrollTop = nodeElement.offsetTop;
            bgFade(nodeElement);
        }
        return undefined;
    }

    Array.from(protyleElement.querySelectorAll(`[data-node-id="${id}"]`)).find((item: HTMLElement) => {
        if (!isInEmbedBlock(item)) {
            nodeElement = item;
            return true;
        }
    });
    if (nodeElement) {
        scrollCenter(protyle, nodeElement, position);
        bgFade(nodeElement);
        return nodeElement;// 仅配合前进后退使用
    }
    if (id === protyle.block.rootID && protyle.options.render.title && protyle.title.editElement) {
        bgFade(protyle.title.editElement);
        return protyle.title.editElement;
    }
};

export const scrollCenter = (
    protyle: IProtyle,
    nodeElement?: Element,
    position: ScrollLogicalPosition = "nearest",
    behavior: ScrollBehavior = "auto"
) => {
    if (!protyle.disabled && !nodeElement && getSelection().rangeCount > 0) {
        const range = getSelection().getRangeAt(0);
        const blockElement = hasClosestBlock(range.startContainer);
        if (blockElement) {
            // https://github.com/siyuan-note/siyuan/issues/10769
            if (blockElement.classList.contains("code-block")) {
                const brElement = document.createElement("br");
                range.insertNode(brElement);
                brElement.scrollIntoView({block: position, behavior});
                brElement.remove();
                return;
            }

            if (blockElement.classList.contains("av") && blockElement.dataset.render === "true") {
                // undo 时禁止数据库滚动
                if (blockElement.querySelector(".av__row--header")?.getAttribute("style")?.indexOf("transform") > -1 ||
                    blockElement.querySelector(".av__row--footer")?.getAttribute("style")?.indexOf("transform") > -1) {
                    return;
                }
                const activeElement = blockElement.querySelector(".av__cell--select, .av__row--select, .av__gallery-item--select");
                if (activeElement) {
                    activeElement.scrollIntoView({block: position, behavior});
                } else {
                    blockElement.scrollIntoView({block: position, behavior});
                }
                return;
            }
            // 撤销时 br 插入删除会导致 rang 被修改 https://github.com/siyuan-note/siyuan/issues/12679
            const cloneRange = range.cloneRange();
            const br2Element = document.createElement("br");
            range.insertNode(br2Element);
            const editorElement = protyle.contentElement;
            const cursorTop = br2Element.getBoundingClientRect().top - editorElement.getBoundingClientRect().top;
            let scrollTop = 0;
            if (cursorTop < 0) {
                scrollTop = editorElement.scrollTop + cursorTop;
            } else if (cursorTop > editorElement.clientHeight - 74) {   // 74 = 移动端底部 + 段落块高度
                scrollTop = editorElement.scrollTop + (cursorTop + 74 - editorElement.clientHeight);
            }
            if (scrollTop !== 0) {
                editorElement.scroll({top: scrollTop, behavior});
            }
            br2Element.remove();
            focusByRange(cloneRange);
            return;
        }
    }

    if (!nodeElement &&
        // https://github.com/siyuan-note/siyuan/issues/11175
        document.activeElement?.tagName !== "TEXTAREA" && document.activeElement?.tagName !== "INPUT") {
        nodeElement = hasClosestBlock(getEditorRange(protyle.wysiwyg.element).startContainer) as HTMLElement;
    }
    if (!nodeElement) {
        return;
    }
    const elementRect = nodeElement.getBoundingClientRect();
    const contentRect = protyle.contentElement.getBoundingClientRect();
    if (position === "start") {
        protyle.contentElement.scroll({
            top: protyle.contentElement.scrollTop + elementRect.top - contentRect.top,
            behavior
        });
        return;
    }
    if (position === "nearest") {
        // 在可视区域内不进行滚动
        if (elementRect.top < contentRect.top) {
            protyle.contentElement.scroll({
                top: protyle.contentElement.scrollTop + elementRect.top - contentRect.top,
                behavior
            });
        } else if (elementRect.bottom > contentRect.bottom) {
            protyle.contentElement.scroll({
                top: protyle.contentElement.scrollTop + elementRect.bottom - contentRect.bottom,
                behavior
            });
        }
        return;
    }
    if (position === "center") {
        protyle.contentElement.scroll({
            top: protyle.contentElement.scrollTop + elementRect.top - (contentRect.top + contentRect.height / 2),
            behavior
        });
    }
};
